// websocket-client.js
// WebSocket客户端，用于连接到后端WebSocket服务器并接收实时数据

console.log('websocket-client.js文件开始加载');

/**
 * PendulumWebSocket类，负责WebSocket连接和数据处理
 */
export class PendulumWebSocket {
  constructor() {
    this.socket = null;
    this.connected = false;
    this.reconnectInterval = 2000; // 重连间隔，单位毫秒
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 10; // 增加最大重连次数
    this.url = 'ws://127.0.0.1:5001'; // WebSocket服务器地址
    this.callbacks = {
      onPendulumState: [],
      onAngleHistory: [],
      onPositionHistory: [],
      onLogs: [],
      onSerialLogs: [],
      onConnect: [],
      onDisconnect: [],
      onError: []
    };
    
    // 自动连接
    this.connect();
    
    // 添加日志处理
    this.onLogs(this._updateBackendLog.bind(this));
    this.onSerialLogs(this._updateSerialLog.bind(this));
  }
  
  /**
   * 连接到WebSocket服务器
   */
  connect() {
    if (this.socket) {
      this.socket.close();
    }
    
    try {
      console.log(`正在连接WebSocket服务器: ${this.url}`);
      this.socket = new WebSocket(this.url);
      
      this.socket.onopen = () => {
        console.log('WebSocket连接已建立');
        this.connected = true;
        this.reconnectAttempts = 0;
        this._triggerCallbacks('onConnect');
        
        // 连接成功后请求初始数据
        this.requestState();
        this.requestAngleHistory();
        this.requestPositionHistory();
        this.requestLogs();
        this.requestSerialLogs();
      };
      
      this.socket.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data);
          this._handleMessage(data);
        } catch (error) {
          console.error('解析WebSocket消息失败:', error);
        }
      };
      
      this.socket.onclose = (event) => {
        console.log(`WebSocket连接已关闭，代码: ${event.code}, 原因: ${event.reason}`);
        this.connected = false;
        this._triggerCallbacks('onDisconnect');
        this._scheduleReconnect();
      };
      
      this.socket.onerror = (error) => {
        console.error('WebSocket错误:', error);
        this._triggerCallbacks('onError', error);
      };
    } catch (error) {
      console.error('创建WebSocket连接失败:', error);
      this._scheduleReconnect();
    }
  }
  
  /**
   * 安排重新连接
   * @private
   */
  _scheduleReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      console.log(`尝试重新连接 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
      setTimeout(() => this.connect(), this.reconnectInterval);
    } else {
      console.error(`达到最大重连次数 (${this.maxReconnectAttempts})，停止重连`);
    }
  }
  
  /**
   * 处理接收到的WebSocket消息
   * @param {Object} data - 解析后的消息数据
   * @private
   */
  _handleMessage(data) {
    const type = data.type;
    
    switch (type) {
      case 'pendulum_state':
        this._triggerCallbacks('onPendulumState', data.data);
        break;
      case 'angle_history':
        this._triggerCallbacks('onAngleHistory', data.data.history);
        break;
      case 'position_history':
        this._triggerCallbacks('onPositionHistory', data.data.history);
        break;
      case 'logs':
        this._triggerCallbacks('onLogs', data.data.log);
        break;
      case 'serial_logs':
        this._triggerCallbacks('onSerialLogs', data.data.log);
        break;
      default:
        console.log('收到未知类型的WebSocket消息:', type, data);
    }
  }
  
  /**
   * 触发回调函数
   * @param {string} event - 事件名称
   * @param {*} data - 回调数据
   * @private
   */
  _triggerCallbacks(event, data = null) {
    if (this.callbacks[event]) {
      for (const callback of this.callbacks[event]) {
        try {
          callback(data);
        } catch (error) {
          console.error(`执行${event}回调时出错:`, error);
        }
      }
    }
  }
  
  /**
   * 发送消息到WebSocket服务器
   * @param {Object} message - 要发送的消息对象
   */
  send(message) {
    if (!this.connected) {
      console.warn('WebSocket未连接，无法发送消息');
      return false;
    }
    
    try {
      this.socket.send(JSON.stringify(message));
      return true;
    } catch (error) {
      console.error('发送WebSocket消息失败:', error);
      return false;
    }
  }
  
  /**
   * 请求当前摆状态
   */
  requestState() {
    return this.send({ command: 'get_state' });
  }
  
  /**
   * 请求角度历史数据
   */
  requestAngleHistory() {
    return this.send({ command: 'get_angle_history' });
  }
  
  /**
   * 请求位置历史数据
   */
  requestPositionHistory() {
    return this.send({ command: 'get_position_history' });
  }
  
  /**
   * 请求后端日志
   */
  requestLogs() {
    return this.send({ command: 'get_log' });
  }
  
  /**
   * 请求串口日志
   */
  requestSerialLogs() {
    return this.send({ command: 'get_serial_log' });
  }
  
  /**
   * 发送按键命令
   * @param {string} key - 按键
   * @param {Object} extra - 附加数据
   */
  sendKey(key, extra = {}) {
    return this.send({
      command: 'pendulum_key',
      key: key,
      ...extra
    });
  }
  
  /**
   * 设置HSV阈值
   * @param {Array} lower - HSV下限
   * @param {Array} upper - HSV上限
   */
  setHsv(lower, upper) {
    return this.send({
      command: 'set_hsv',
      lower: lower,
      upper: upper
    });
  }
  
  /**
   * 添加摆状态更新回调
   * @param {Function} callback - 回调函数
   */
  onPendulumState(callback) {
    this.callbacks.onPendulumState.push(callback);
  }
  
  /**
   * 添加角度历史数据更新回调
   * @param {Function} callback - 回调函数
   */
  onAngleHistory(callback) {
    this.callbacks.onAngleHistory.push(callback);
  }
  
  /**
   * 添加位置历史数据更新回调
   * @param {Function} callback - 回调函数
   */
  onPositionHistory(callback) {
    this.callbacks.onPositionHistory.push(callback);
  }
  
  /**
   * 添加日志更新回调
   * @param {Function} callback - 回调函数
   */
  onLogs(callback) {
    this.callbacks.onLogs.push(callback);
  }
  
  /**
   * 添加串口日志更新回调
   * @param {Function} callback - 回调函数
   */
  onSerialLogs(callback) {
    this.callbacks.onSerialLogs.push(callback);
  }
  
  /**
   * 添加连接成功回调
   * @param {Function} callback - 回调函数
   */
  onConnect(callback) {
    this.callbacks.onConnect.push(callback);
  }
  
  /**
   * 添加连接断开回调
   * @param {Function} callback - 回调函数
   */
  onDisconnect(callback) {
    this.callbacks.onDisconnect.push(callback);
  }
  
  /**
   * 添加错误回调
   * @param {Function} callback - 回调函数
   */
  onError(callback) {
    this.callbacks.onError.push(callback);
  }
  
  /**
   * 关闭WebSocket连接
   */
  close() {
    if (this.socket) {
      this.socket.close();
      this.socket = null;
    }
  }
  
  /**
   * 更新后端日志
   * @param {Array} logs - 日志数据
   * @private
   */
  _updateBackendLog(logs) {
    const logDiv = document.getElementById('backendLog');
    if (logDiv && logs) {
      logDiv.innerHTML = logs.map(line => `<div>${line}</div>`).join('');
      logDiv.scrollTop = logDiv.scrollHeight; // 自动滚动到最底部
    }
  }
  
  /**
   * 更新串口日志
   * @param {Array} logs - 日志数据
   * @private
   */
  _updateSerialLog(logs) {
    const logDiv = document.getElementById('serialLog');
    if (logDiv && logs) {
      logDiv.innerHTML = logs.map(line => `<div>${line}</div>`).join('');
      logDiv.scrollTop = logDiv.scrollHeight;
    }
  }
}

// 创建全局实例
export const pendulumWebSocket = new PendulumWebSocket();

// 导出全局实例
window.pendulumWebSocket = pendulumWebSocket; 